package com.gitee.ywj1352.leecode;

import org.junit.Test;

/**
 * Created by wenjie.yang on 2019/7/24.
 */
public class Solution {
    private static Solution solution = new Solution();

    /**
     * 输入: [7,1,5,3,6,4]
     * 输出: 5
     * 解释: 在第 2 天（股票价格 = 1）的时候买入，在第 5 天（股票价格 = 6）的时候卖出，最大利润 = 6-1 = 5 。
     * 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
     */
    public static int maxProfit(int[] prices) {
        int min = Integer.MAX_VALUE;
        int maxC = 0;
        for (int i = 0; i < prices.length; i++) {
            int dq = prices[i];
            if (dq < min) {
                min = dq;
            }
            if (dq - min > maxC) {
                maxC = dq - min;
            }
        }
        return maxC;
    }


    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    /**
     * 两数相加
     * 输入：(2 -> 4 -> 3) + (5 -> 6 -> 4)
     * 输出：7 -> 0 -> 8
     * 原因：342 + 465 = 807
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode nowL1, nowL2, returnL = null, nowReturnL = null;
        nowL1 = l1;
        nowL2 = l2;
        int jw = 0;
        //判断是否在进行 循环
        while (nowL1 != null || nowL2 != null || jw == 1) {
            int inowL1 = nowL1 == null ? 0 : nowL1.val,
                    inowL2 = nowL2 == null ? 0 : nowL2.val;
            int i = inowL1 + inowL2 + jw;
            if (returnL == null) {
                returnL = new ListNode(i % 10);
            } else {
                ListNode listNode = new ListNode(i % 10);
                if (nowReturnL == null) {
                    returnL.next = listNode;
                    nowReturnL = listNode;
                } else {
                    nowReturnL.next = listNode;
                    nowReturnL = listNode;
                }
            }
            if (i > 9) {
                jw = 1;
            } else {
                jw = 0;
            }
            nowL1 = nowL1 == null ? null : nowL1.next;
            nowL2 = nowL2 == null ? null : nowL2.next;
        }
        return returnL;
    }

    @Test
    //(2 -> 4 -> 3) + (5 -> 6 -> 4)
    public void addTwoNumbersTest() {
        ListNode l1 = new ListNode(1);
        ListNode ll1 = new ListNode(9);
        ListNode ll2 = new ListNode(9);
        ll1.next = ll2;
        ListNode listNode = solution.addTwoNumbers(l1, ll1);
        System.out.println(listNode);
    }


    /**
     * 输入: [7,1,5,3,6,4]
     * 输出: 7
     * 解释: 在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     *      随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
     *
     * @param prices
     * @return
     */
    public int maxProfit2(int[] prices) {
        int max = 0;
        if (prices.length == 0) {
            return max;
        }
        int[] arr = new int[prices.length - 1];
        //i 是第几天买 股票
        for (int i = 1; i < prices.length; i++) {
            int cha = prices[i] - prices[i - 1];
            arr[i - 1] = cha;
        }

        for (int i = 1; i < arr.length; i++) {


        }
        return 0;
    }

    private int sum(int[] arr, int s, int e) {
        int sum = 0;
        for (int i = s; i < e; i++) {
            sum += arr[i];
        }
        return sum;
    }

    public int maxProfit3(int[] prices) {
        /**
         对于任意一天考虑四个变量:
         fstBuy: 在该天第一次买入股票可获得的最大收益
         fstSell: 在该天第一次卖出股票可获得的最大收益
         secBuy: 在该天第二次买入股票可获得的最大收益
         secSell: 在该天第二次卖出股票可获得的最大收益
         分别对四个变量进行相应的更新, 最后secSell就是最大
         收益值(secSell >= fstSell)
         **/
        int fstBuy = Integer.MIN_VALUE, fstSell = 0;
        int secBuy = Integer.MIN_VALUE, secSell = 0;
        for (int p : prices) {
            fstBuy = Math.max(fstBuy, -p);
            fstSell = Math.max(fstSell, fstBuy + p);
            secBuy = Math.max(secBuy, fstSell - p);
            secSell = Math.max(secSell, secBuy + p);
        }
        return secSell;
    }

    @Test
    public void maxProfit2Test() {
        int[] arr = {3, 3, 5, 0, 0, 3, 1, 4};
        int i = solution.maxProfit3(arr);
        System.out.println(i);
    }


    /**
     * 称为 感染函数把有关系的 '1' 变成 '0'
     * 深度 优先的把 '1' 变成'0'
     *
     * @param grid
     * @param r
     * @param c
     */
    void dfs(char[][] grid, int r, int c) {
        int nr = grid.length;
        int nc = grid[0].length;

        if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {
            return;
        }

        grid[r][c] = '0';
        dfs(grid, r - 1, c);
        dfs(grid, r + 1, c);
        dfs(grid, r, c - 1);
        dfs(grid, r, c + 1);
    }

    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }

        int nr = grid.length;
        int nc = grid[0].length;
        int num_islands = 0;
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_islands;
                    dfs(grid, r, c);
                }
            }
        }
        return num_islands;
    }


}
